package com.atguigu.service.impl;

import com.atguigu.common.config.exception.MyException;
import com.atguigu.mapper.SysMenuMapper;
import com.atguigu.mapper.SysRoleMenuMapper;
import com.atguigu.model.system.SysMenu;
import com.atguigu.model.system.SysRoleMenu;
import com.atguigu.service.SysMenuService;
import com.atguigu.utils.MenuHelper;
import com.atguigu.vo.system.AssginMenuVo;
import com.atguigu.vo.system.MetaVo;
import com.atguigu.vo.system.RouterVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Override
    public List<SysMenu> findNodes() {
        List<SysMenu> sysMenus = baseMapper.selectList(null);
        return MenuHelper.buildTree(sysMenus);

    }

    @Override
    public void deleteById(Integer id) {
        LambdaQueryWrapper<SysMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysMenu::getParentId, id.intValue());
        Integer integer = baseMapper.selectCount(lambdaQueryWrapper);
        if (integer > 0) {
            throw new MyException(201, "当前菜单存在子菜单，禁止删除！");
        }
        baseMapper.deleteById(id);
    }

    @Override
    public void switchStatus(Integer id, Integer status) {
        LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
        SysMenu sysMenu = new SysMenu();
        if (status == 1) {
            sysMenu.setStatus(0);
        } else {
            sysMenu.setStatus(1);
        }
        wrapper.eq(SysMenu::getId, id);
        baseMapper.update(sysMenu, wrapper);
    }

    @Override
    public List<SysMenu> toAssign(Long roleId) {
       /* //1.获取菜单集合
        LambdaQueryWrapper<SysMenu> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(SysMenu::getStatus,1);
        List<SysMenu> AllSysMenus = baseMapper.selectList(wrapper);

        //2.获取角色已选中的菜单
        LambdaQueryWrapper<SysRoleMenu> wrapper1=new LambdaQueryWrapper<>();
        wrapper1.eq(SysRoleMenu::getRoleId,roleId);
        List<SysRoleMenu> SelectedSysRoleMenus = sysRoleMenuMapper.selectList(wrapper1);

        //3.获取角色已选中的菜单id
        List<Long> idList = SelectedSysRoleMenus.stream().map(sysRoleMenu -> sysRoleMenu.getMenuId()).collect(Collectors.toList());

        //4.和所有菜单相比较
        for (Long aLong : idList) {
            for (SysMenu sysMenu : AllSysMenus) {
                    if (sysMenu.getId().longValue()==aLong.longValue()){
                        sysMenu.setSelect(true);
                    }
            }
        }*/
        List<SysMenu> AllSysMenus = sysMenuMapper.getMenuList(roleId);
        return MenuHelper.buildTree(AllSysMenus);

    }

    @Override
    public void doAssign(AssginMenuVo assginMenuVo) {
        //1.根据角色id删除所有权限
        Long roleId = assginMenuVo.getRoleId();
        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenu::getRoleId, roleId);
        sysRoleMenuMapper.delete(wrapper);
        //2.为当前角色id分配权限
        List<Long> menuIdList = assginMenuVo.getMenuIdList();
        if (!CollectionUtils.isEmpty(menuIdList)) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(roleId);
            for (Long aLong : menuIdList) {
                sysRoleMenu.setMenuId(aLong);
                sysRoleMenuMapper.insert(sysRoleMenu);
            }
        }

    }

    /**
     * @param sysMenus
     * @return
     */
    @Override
    public List<RouterVo> getRouterVoList(List<SysMenu> sysMenus) {
        List<RouterVo> routerVoList = new ArrayList<>();
        for (SysMenu sysMenu : sysMenus) {
            RouterVo routerVo = new RouterVo();
            routerVo.setPath(buildPath(sysMenu));
            routerVo.setAlwaysShow(false);
            routerVo.setHidden(false);
            routerVo.setComponent(sysMenu.getComponent());
            routerVo.setMeta(new MetaVo(sysMenu.getName(), sysMenu.getIcon()));
            List<SysMenu> children = sysMenu.getChildren();
            /**
             * 因为这里收集的是菜单，因此判断如果type为1就表示是菜单，
             * 就不需要再往下收集路由了
             */
            if (sysMenu.getType().intValue() == 1) {
                //如果是菜单 找到其下还存在path和component的按钮
                //隐藏路由单独列出没有层级关系

                List<SysMenu> hiddenMenuList = children.stream().filter(item -> !StringUtils.isEmpty(item.getPath())).collect(Collectors.toList());
                for (SysMenu menu : hiddenMenuList) {
                    RouterVo routerVo1 = new RouterVo();
                    routerVo1.setHidden(true);
                    routerVo1.setComponent(menu.getComponent());
                    routerVo1.setPath(menu.getPath());
                    routerVo1.setAlwaysShow(false);
                    routerVo1.setMeta(new MetaVo(menu.getName(), menu.getIcon()));
                    routerVoList.add(routerVo1);
                }
            }else{
                if (children.size()>0){
                    routerVo.setAlwaysShow(true);
                }
                routerVo.setChildren(getRouterVoList(children));

            }
            routerVoList.add(routerVo);
        }
        return routerVoList;
    }


    private String buildPath(SysMenu sysMenu) {
        String resultPath = "/" + sysMenu.getPath();
        if (sysMenu.getParentId().longValue() != 0) {
            resultPath = sysMenu.getPath();
        }
        return resultPath;
    }

    @Override
    public List<String> getPermsList( List<SysMenu> sysMenus,Long userId) {
        List<String> strings=new ArrayList<>();
        for (SysMenu sysMenu : sysMenus) {
            if (sysMenu.getType().intValue()==2){
                strings.add(sysMenu.getPerms());
            }
        }
        return strings;
    }
}
